from jinja2 import Template
import json
import os
import pathlib
from utils.yaml_utils import read_yaml_all
from utils.file_dir import get_testcase_dir


# 修改后的模板 - 支持多个测试用例
# test_suite_template = Template("""\
# import pytest
# import allure
# import json
# from utils.yaml_utils import read_yaml_all
# from utils.assertion_utils import AssertionUtils
#
# {% for test_case in test_cases %}
# @allure.feature("{{ test_case.feature }}")
# @allure.description('{{ test_case.description }}')
# @allure.story("{{ test_case.story }}")
# @allure.title("{{ test_case.title }}")
# @allure.severity(allure.severity_level.{{ test_case.severity }})
# def {{ test_case.name }}(api):
#     test_data = {
#         "url": "{{ test_case.url }}",
#         "method": "{{ test_case.method }}",
#         "headers": {{ test_case.headers | tojson }},
#         "{{ test_case.request }}": {{ test_case.params | tojson }},
#     }
#
#     with allure.step("1. 准备测试数据"):
#         api.log.info(f"测试数据准备完成: {test_data}")
#
#     with allure.step("2. 发送接口请求"):
#         res = api.requests_utils(**test_data)
#         api.log.info(f"请求完成，状态码: {res.status_code}")
#
#     with allure.step("3. 记录响应结果"):
#         response_json = res.json()
#         api.log.info(f"响应内容: {response_json}")
#
#     # 执行断言
#     with allure.step("4. 执行断言"):
#         expected = {{ test_case.expected | tojson }}
#
#         # 1. 状态码断言
#         AssertionUtils().assert_status_code(res, expected["status_code"])
#
#         # 2. 响应体结构断言（如果存在）
#         if expected.get("response"):
#             response_json = res.json()
#             AssertionUtils().assert_response_fields(response_json, expected["response"])
#
#
#         api.log.info("✅ 所有断言通过")
#
# {% endfor %}
# """)


test_suite_template = Template("""\
import pytest
import allure
import json
from utils.yaml_utils import read_yaml_all
from utils.assertion_utils import AssertionUtils

class TestCase:

    {% for test_case in test_cases %}
    @allure.feature("{{ test_case.feature }}")
    @allure.description('{{ test_case.description }}')
    @allure.story("{{ test_case.story }}")
    @allure.title("{{ test_case.title }}")
    @allure.severity(allure.severity_level.{{ test_case.severity }})
    def {{ test_case.name }}(self, api):
        test_data = {
            "url": "{{ test_case.url }}",
            "method": "{{ test_case.method }}",
            "headers": {{ test_case.headers | tojson }},
            "{{ test_case.request }}": {{ test_case.params | tojson }},
        }

        with allure.step("1. 准备测试数据"):
            api.log.info(f"测试数据准备完成: {test_data}")

        with allure.step("2. 发送接口请求"):
            res = api.requests_utils(**test_data)
            api.log.info(f"请求完成，状态码: {res.status_code}")

        with allure.step("3. 记录响应结果"):
            response_json = res.json()
            api.log.info(f"响应内容: {response_json}")

        # 执行断言
        with allure.step("4. 执行断言"):
            expected = {{ test_case.expected | tojson }}

            # 1. 状态码断言
            AssertionUtils().assert_status_code(res, expected["status_code"])

            # 2. 响应体结构断言（如果存在）
            if expected.get("response"):
                response_json = res.json()
                AssertionUtils().assert_response_fields(response_json, expected["response"])


            api.log.info("✅ 所有断言通过")

    {% endfor %}
""")

def case_template(test_data_file, test_cases_name):
    """
    :param test_data_file: 测试数据文件
    :param test_cases_name: 测试用例.py文件的名称
    :return: none
    """
    if str(test_data_file).endswith(".yaml"):
        # 读取YAML数据
        test_cases = read_yaml_all(test_data_file)

        # 确保数据是列表形式
        if not isinstance(test_cases, list):
            test_cases = [test_cases]  # 包装成列表

        # 修改渲染逻辑，处理None值
        def tojson_filter(data):
            if data is None:
                return 'null'
            return json.dumps(data, ensure_ascii=False)

        generated_test_suite = test_suite_template.render(
            test_cases=test_cases,
            tojson=tojson_filter
        )
        # 渲染测试套件
        # generated_test_suite = test_suite_template.render(
        #     test_cases=test_cases,
        #     tojson=lambda d: json.dumps(d, ensure_ascii=False)
        # )

        # 获取文件路径
        file_path = pathlib.Path(f"{get_testcase_dir()}/{test_cases_name}.py")

        # 确保目录存在
        dir_path = file_path.parent
        # 创建目录（如果不存在）
        dir_path.mkdir(parents=True, exist_ok=True)

        # 生成代码文件（覆盖写入）
        with open(file_path, "w", encoding="utf-8") as f:
            f.write(generated_test_suite)

# case_template("test_cases.yaml", "test_sessiondetail")
